/*
 * MediaRecorder.h
 *
 *  Created on: 2017年3月1日
 *      Author: chuanjiang.zh
 */

#ifndef MEDIARECORDER_H_
#define MEDIARECORDER_H_

#include "BasicType.h"
#include "MFormat.h"

namespace av
{

#ifndef MediaFileFormat_ENUM
#define	MediaFileFormat_ENUM

enum MediaFileFormat
{
	FILE_AUTO = -1,	/// 自动分析
	FILE_RAW = 0,	/// 原始文件,用于dump
	FILE_TS,
	FILE_MP4,
	FILE_PS,
	FILE_AVI
};

#endif // MediaFileFormat_ENUM

enum MediaWriterStatus
{
	MEDIA_WRITER_OPENED = 0x1000,
	MEDIA_WRITER_CLOSED,
	MEDIA_WRITER_IO_ERROR
};

class MediaWriterListener;

class DLLEXPORT MediaWriter
{
public:

public:
	virtual ~MediaWriter() {}

	/**
	 * 打开文件
	 * @param filename	文件名
	 * @param fmt		媒体格式
	 * @return
	 */
	virtual bool open(const char* filename, const MFormat& fmt) =0;

	virtual void close() =0;

	virtual bool isOpen() =0;

	virtual bool getFormat(MFormat& fmt) =0;

	/**
	 * 写入视频.
	 * 图像数据是一维字节数组
	 * @param data		视频包指针
	 * @param size		视频包长度
	 * @param pts		时间戳, 单位为1/90000秒, <0 表示内部自动生成.
     * @param flags     标识
	 * @return true 表示成功
	 */
    virtual bool writeVideo(uint8_t* data, int size, int64_t pts, int flags) =0;


	/**
	 * 写入音频
	 * 数据是一维字节数组
     * @param sampleRate 采样率
     * @param channels   通道数
     * @param sampleFormat 采样格式 @see AVSampleFormat
	 * @param data	数据指针
	 * @param size	数据长度
	 * @param pts	时间戳, 单位为1/90000秒
	 * @return
	 */
    virtual bool writeAudio(uint8_t* data, int size, int64_t pts, int flags) =0;

    /**
     * 获取写入时长, 单位为秒
     * @return
     */
    virtual int getDuration() =0;

    /**
     * 获取字节长度
     * @return
     */
    virtual int64_t getByteLength() =0;

    /**
     * 设置输出文件路径. 可用于切换录像
     * @param filepath	文件路径
     * @return true 表示成功
     */
    virtual bool setFile(const char* filepath) =0;

    /**
     * 转码音频流.
     * 该函数必须在open之前调用
     * @param codecId	音频编码
     * @return true 表示成功
     */
    virtual bool setOutputAudioCodec(int codecId) =0;

	virtual void setListener(MediaWriterListener* listener) =0;

	/**
	 * 设置媒体元信息
	 * @param key	键
	 * @param value 值
	 * @param size  值长度
	 * @return true 表示成功
	 */
	virtual bool setMeta(const char* key, const char* value, int size) = 0;

};

class MediaWriterListener
{
public:
	virtual ~MediaWriterListener() {}

	virtual void onWriteStatus(MediaWriter* writer, int status) =0;
};


class DLLEXPORT MediaWriterFactory
{
public:


public:
	static void startup();

	static void cleanup();

	/**
	 * 获取文件格式对应的默认文件名后缀, 比如".ts", ".mp4"
	 * @param fileFormat
	 * @return 文件名后缀
	 */
	static const char* getFileExt(MediaFileFormat fileFormat);

	/**
	 * 创建媒体写入对象
	 * @param fileFormat	文件格式,@see MediaFileFormat
	 * @return
	 */
	static MediaWriter* create(MediaFileFormat fileFormat);

	static MediaWriter* createPsInputWriter(MediaFileFormat fileFormat);

	static MediaWriter* createNormWriter(MediaFileFormat fileFormat);

	/**
	 * 销毁媒体写入对象
	 * @param writer
	 */
	static void destroy(MediaWriter* writer);


	static bool guessFileFormat(const char* filename, MediaFileFormat& fileFormat);


	MediaWriterFactory()
	{
		startup();
	}

	~MediaWriterFactory()
	{
		cleanup();
	}


};





}


#endif /* MEDIARECORDER_H_ */
